<?php
/****************************************************************************
Source taken from: Marco Von Ballmoos
http://www.earthli.com/software/webcore
http://earthli.com/software/browser_detector/
Was version 2.8.0 -- Now something different
Some additions and changes taken from version 3.2 (January 4, 2010)
I've chopped a lot of comments and carriage returns out of it, and diddled a thing or two, here and there. - msoja
****************************************************************************/

define ('Browser_netscape_4', 'netscape_4');
define ('Browser_gecko', 'gecko');
define ('Browser_khtml', 'khtml');
define ('Browser_opera', 'opera');
define ('Browser_presto', 'presto');
define ('Browser_webtv', 'webtv');
define ('Browser_ie', 'ie');
define ('Browser_icab', 'icab');
define ('Browser_omniweb', 'omniweb');
define ('Browser_text', 'lynx');
//define ('Browser_robot', 'robot');
define ('Browser_newsreader', 'newsreader');
define ('Browser_previewer', 'previewer');
define ('Browser_os_windows', 'windows');
define ('Browser_os_mac', 'macos');
define ('Browser_os_linux', 'linux');
define ('Browser_unknown', 'Unknown');

/***************************************/
class USER_AGENT {
var $user_agent_string;

/***************************************/
function load_from_string ($s) {
$this->user_agent_string = $s;
$tables = $this->_make_user_agent_parse_tables();
$parser = $this->_make_user_agent_parser ($tables);
$this->_ua = $parser->make_properties_from($s);
}
/***************************************/
function renderer_name () {
return $this->_ua->renderer_name;
}
/***************************************/
function renderer_version () {
return $this->_ua->renderer_version;
}
/***************************************/
function name () {
return $this->_ua->name;
}
/***************************************/
function version () {
return $this->_ua->version;
}
/***************************************/
function system_name () {
return $this->_ua->system_name;
}
/***************************************/
function system_version () {
return $this->_ua->system_version;
}
/***************************************/
function calculated_system_name () {
return $this->_ua->calculated_system_name;
}
/***************************************/
function system_id () {
if (isset ($this->_ua->system_name)) {
	$Result = $this->_ua->system_name;
	if ($this->_ua->system_version)
		$Result .= ' ' . $this->_ua->system_version;
	if (strcasecmp ($this->_ua->system_name, $this->_ua->calculated_system_name) != 0)
		$Result .= ' (' . $this->_ua->calculated_system_name . ')';
	return $Result;
	}
else
	return $this->_ua->calculated_system_name;
}
/***************************************/
function gecko_date () {
return $this->_ua->gecko_date;
}
/***************************************/
function is ($code) {
return (isset ($this->_ua->renderer_id) && ($code == $this->_ua->renderer_id)) || (isset ($this->_ua->os_id) && ($code == $this->_ua->os_id));
}
/***************************************/
function _make_user_agent_parse_tables () {
return new USER_AGENT_PARSE_TABLES ();
}
/***************************************/
function _make_user_agent_parser ($tables) {
return new USER_AGENT_PARSER ($tables);
}
} //class USER AGENT

/***************************************/
class USER_AGENT_PROPERTIES {
var $name = Browser_unknown;
var $version = '';
var $renderer_name = Browser_unknown;
var $renderer_version = '';
var $renderer_id = Browser_unknown;
var $system_name = Browser_unknown;
var $system_version = '';
var $calculated_system_name = Browser_unknown;
var $os_id = '';
var $gecko_date = 0;
//public $is_robot;
var $major_version = 0;
var $minor_version = 0;
var $build_number = 0;
} //class USER_AGENT_PROPERTIES

/***************************************/
class USER_AGENT_PARSER {

/***************************************/
function USER_AGENT_PARSER ($tables) {
$this->_tables = $tables;
}

/***************************************/
function make_properties_from ($s) {

$Result = new USER_AGENT_PROPERTIES ();

$parts = array();
preg_match_all ('/(\w[-&\w ]*[-&\w]+)[-\/: ]([vV]?[0-9][0-9a-z]*([\.-][0-9][0-9a-z]*)*)/', $s, $parts); //version 2.8
//preg_match_all ('/([a-zA-Z]|[a-zA-Z]+[0-9]+|[a-zA-Z]+[ 0-9]+[a-zA-Z]|[a-zA-Z][ \-&a-zA-Z]*[a-zA-Z])[-\/: ]?[vV]?([0-9][0-9a-z]*([\.-][0-9][0-9a-z]*)*)/', $s, $parts); //version 3.2
//preg_match_all ('/([a-zA-Z]|[a-zA-Z]+[0-9]+|[a-zA-Z]+[ 0-9]+[a-zA-Z]|[a-zA-Z][ \-&a-zA-Z]*[a-zA-Z])[-\/: ]?[vV]?([0-9][0-9a-z]*([\.-][0-9][0-9a-z]*)*)/', $s, $parts);

$ids = $parts[1];
$vers = $parts[2];

$superfluous_ids = $this->_tables->superfluous_ids ();
$system_ids = $this->_tables->system_ids ();
$renderers = $this->_tables->renderer_ids ();

$index = 0;
$current_renderer = null;
$continue_processing = true;
$browser_is_final = false;

while ($continue_processing && ($index < sizeof($ids))) {
	$ver = ltrim($vers[$index], "vV");
	$id = strtolower($ids[$index]);
//	echo $id . "::" . $ver . "<br />";

	if (strcasecmp(substr($id, -2), ' v') == 0){
		$id = substr($id, 0, -2);
		$ids [$index] = substr($ids [$index], 0, -2);
		}

	if (strlen($id) > 1) {
		if (isset ($renderers[$id])) {
			$renderer = $renderers[$id];
			if (empty ($current_renderer) || ($current_renderer->renderer_can_be_overridden ())) {
				if ($renderer->is_mozilla_gecko ($ver))
					$current_renderer = $renderers [Browser_gecko];
				else
					$current_renderer = $renderer;

				if ($id == Browser_gecko)
					$Result->gecko_date = $this->_determine_gecko_date ($ver);
				else
					$current_version = $ver;
				}
			}
		}

	if (!isset($superfluous_ids [$id]) && !isset($system_ids[$id])) {
		if (!$browser_is_final && (empty ($current_renderer) || $current_renderer->browser_can_be_overridden ())) {
			$Result->version = $ver;
			if (isset ($renderers [$id])) {
				$renderer = $renderers [$id];
				if ($renderer->is_mozilla_gecko ($ver))
					$Result->name = 'Mozilla';
				else
					$Result->name = $renderer->display_name;

				if ($current_renderer->precedence == User_agent_final_browser_temporary_renderer)
					$browser_is_final = true;

				$continue_processing = $renderer->continue_processing_ids ();
				}
			else
				$Result->name = $ids [$index]; // Use the id in original case
			}
		}

	if (isset ($system_ids [$id])) {
		$Result->system_name = $system_ids [$id];
		$Result->system_version = $ver;
		}

	$index++;
	} //end of while

if (! empty ($current_renderer)) {
	$Result->renderer_id = $current_renderer->id;
	$Result->renderer_name = $current_renderer->technology_name;
	$Result->renderer_version = $current_version;
	@list ($Result->major_version, $Result->minor_version, $Result->build_number) = explode ('.', $Result->renderer_version);

	if (! $current_renderer->browser_can_be_overridden ()) {
		$Result->name = $current_renderer->display_name;
		$Result->version = $Result->renderer_version;
		}
	}

$this->_determine_os ($Result, $s);
//$this->_determine_robot ($Result);

return $Result;
} //make_properties_from

/***************************************/
function _determine_gecko_date ($version) {
$parts = null; // Compiler warning
preg_match ('/([0-9]{4})([0-9]{2})([0-9]{2})/', $version, $parts);
if (sizeof ($parts))
//	return new DATE_TIME (mktime (0, 0, 0, $parts [2], $parts [3], $parts [1]));
	return mktime (0, 0, 0, $parts [2], $parts [3], $parts [1]);
return null;
} //_determine_gecko_date

/***************************************/
function _determine_os ($props, $raw_data) {
$raw_data = strtolower ($raw_data);
$props->calculated_system_name = Browser_unknown;
$oss = $this->_tables->os_ids ();
while (($props->calculated_system_name == Browser_unknown) && (list ($key, $value) = each ($oss))) {
	if ($key) {
		$keys = explode (',', $key);
		$match = TRUE;
		foreach ($keys as $key)
			$match = $match && ($this->_contains ($raw_data, $key));
		if ($match)
			$props->calculated_system_name = $value;
		}
	}

if ($props->system_name == Browser_unknown)
	$props->system_name = $props->calculated_system_name;

if ($this->_contains ($props->calculated_system_name, 'Windows'))
	$props->os_id = Browser_os_windows;
if ($this->_contains ($props->calculated_system_name, 'MacOS'))
	$props->os_id = Browser_os_mac;
if ($this->_contains ($props->calculated_system_name, 'Linux'))
	$props->os_id = Browser_os_linux;
} //_determine_os

/***************************************/
function _contains ($haystack, $needle) {
return strpos ($haystack, $needle) !== FALSE;
}
} //class USER_AGENT_PARSER

/***************************************/
class USER_AGENT_PARSE_TABLES {

/***************************************/
function renderer_ids ()
{
return array (
'mozilla' => new USER_AGENT_RENDERER_INFO (Browser_netscape_4, 'Netscape 4.x', User_agent_temporary_renderer),
'msie' => new USER_AGENT_RENDERER_INFO (Browser_ie, 'Trident (IE)', User_agent_temporary_renderer, 'Internet Explorer'),
'rv' => new USER_AGENT_RENDERER_INFO (Browser_gecko, 'Gecko', User_agent_temporary_renderer, 'Mozilla'),
'gecko' => new USER_AGENT_RENDERER_INFO (Browser_gecko, 'Gecko', User_agent_temporary_renderer, 'Mozilla'),
'shiira' => new USER_AGENT_RENDERER_INFO (Browser_khtml, 'Webcore', User_agent_final_browser_abort, 'Shiira'),
'applewebkit' => new USER_AGENT_RENDERER_INFO (Browser_khtml, 'Webcore', User_agent_final_renderer),
'netscape6' => new USER_AGENT_RENDERER_INFO (Browser_gecko, 'Netscape', User_agent_final_browser),
'chrome' => new USER_AGENT_RENDERER_INFO (Browser_khtml, 'Google Chrome', User_agent_final_browser_abort),
'opera mini' => new USER_AGENT_RENDERER_INFO (Browser_opera, 'Presto (Opera)', User_agent_final_browser_temporary_renderer, 'Opera Mini'),
'opera' => new USER_AGENT_RENDERER_INFO (Browser_opera, 'Presto (Opera)', User_agent_temporary_renderer, 'Opera'),
'presto' => new USER_AGENT_RENDERER_INFO (Browser_presto, 'Presto (Opera)', User_agent_final_renderer, 'Opera'),
'version' => new USER_AGENT_RENDERER_INFO (Browser_presto, 'Presto (Opera)', User_agent_final_browser, 'Opera'),
'konqueror' => new USER_AGENT_RENDERER_INFO (Browser_khtml, 'KHTML', User_agent_final_browser, 'Konqueror'),
'omniweb' => new USER_AGENT_RENDERER_INFO (Browser_omniweb, 'OmniWeb', User_agent_final_browser),
'webtv' => new USER_AGENT_RENDERER_INFO (Browser_webtv, 'WebTV', User_agent_final_browser),
/*
'googlebot' => new USER_AGENT_RENDERER_INFO (Browser_robot, 'Google Robot', User_agent_final_browser),
'msnbot' => new USER_AGENT_RENDERER_INFO (Browser_robot, 'MSN Robot', User_agent_final_browser),
'yahooseeker' => new USER_AGENT_RENDERER_INFO (Browser_robot, 'Yahoo Robot', User_agent_final_browser),
'googlebot-image' => new USER_AGENT_RENDERER_INFO (Browser_robot, 'Google Robot', User_agent_final_browser),
*/
'lynx' => new USER_AGENT_RENDERER_INFO (Browser_text, 'Text', User_agent_final_browser, 'Lynx'),
'icab' => new USER_AGENT_RENDERER_INFO (Browser_icab, 'iCab', User_agent_final_browser),

'applesyndication' => new USER_AGENT_RENDERER_INFO (Browser_newsreader, 'Safari Newsreader', User_agent_final_browser),
'netnewswire' => new USER_AGENT_RENDERER_INFO (Browser_newsreader, 'Net News Wire', User_agent_final_browser),
'yahoofeedseeker' => new USER_AGENT_RENDERER_INFO (Browser_newsreader, 'Yahoo Newsreader', User_agent_final_browser),
'newsgatoronline' => new USER_AGENT_RENDERER_INFO (Browser_newsreader, 'NewsGator', User_agent_final_browser),
'bloglines' => new USER_AGENT_RENDERER_INFO (Browser_newsreader, 'Bloglines', User_agent_final_browser),
'feedfetcher-google' => new USER_AGENT_RENDERER_INFO (Browser_newsreader, 'Google Feedfetcher', User_agent_final_browser),
'newzcrawler' => new USER_AGENT_RENDERER_INFO (Browser_newsreader, 'NewzCrawler', User_agent_final_browser),

'facebookexternalhit' => new USER_AGENT_RENDERER_INFO (Browser_previewer, 'Facebook Preview', User_agent_final_browser)
);
}

/***************************************/
function superfluous_ids () {
return array (
'windows' => 1,
'windows nt' => 1,
'win 9x' => 1,
'linux' => 1,
'debian' => 1,
'suse' => 1,
'amigaos' => 1,
'gecko' => 1,                 // gecko build date
'rv' => 1,                    // gecko version number
'libwww-fm' => 1,             // lynx
'openssl' => 1,               // lynx
'ssl-mm' => 1,                // lynx
'ycomp' => 1,                 // IE plugin
'sbcydsl' => 1,               // IE plugin
'hotbar' => 1,                // IE plugin
'yplus' => 1,                 // IE plugin
'ypc' => 1,                   // IE plugin
'net clr' => 1,               // msn
'i386-unknown-freebsd' => 1,
'libcurl' => 1,
'r1' => 1,
'media center pc' => 1,
'ssl' => 1,
'debian package' => 1,
'winfx runtime' => 1,         // windows vista
'avalon' => 1,                // windows vista
'tablet pc' => 1,             // windows vista
'sl commerce client' => 1,    // windows vista
'system' => 1, //baidu spider
'cldc' => 1,                  // Nokia phone
'midp' => 1,                  // Nokia phone
'vendorid' => 1,							//blackberry
'views' => 1,                 // Newsfeed readers
'subscribers' => 1,           // Newsfeed readers
'users' => 1,	                // Newsfeed readers
'ipv' => 1,
'linux i' => 1,
'com toolbar' => 1,
'ms-rtc lm' => 1,
'ms-rtc ea' => 1,
'slcc1' => 1,
'beta' => 1
,'article' => 1
,'hotbarsearchtoolbar' => 1
,'008' => 1
,'bri' => 1
,'build' => 1
,'mra' => 1
,'com' => 1
,'emusic dlm' => 1
,'wintsi' => 1
,'winnt-pai' => 1
,'asktbasv5' => 1
,'iph' => 1
//lower case 'em
);
/*
,'' => 1
*/
}

/***************************************/
function system_ids () {
return array (
'windows nt' => 'Windows NT',
'win 9x' => 'Windows 9x',
'linux' => 'Linux',
'debian' => 'Debian',
'amigaos' => 'AmigaOS',
'debian package' => 'Debian',
'suse' => 'SUSE',
'series80' => 'Series 80'
);
}

/***************************************/
public function robot_names() {
	return array ('crawler','spider','bot');
}

/***************************************/
function os_ids () {
return array (
'win,nt 6.1' => 'Windows 7',
'win,nt 6.0' => 'Windows Vista',
'win,nt 5.2' => 'Windows Server 2003',
'win,nt 5.1' => 'Windows XP',
'win,nt 5' => 'Windows 2000',
'win,2000' => 'Windows 2000',
'win,9x 4.9' => 'Windows ME',
'win,98' => 'Windows 98',
'win,95' => 'Windows 95',
'win,nt 4' => 'Windows NT 4.x',
'win,nt4' => 'Windows NT 4.x',
'win,3.1' => 'Windows 3.1',
'win,nt 3' => 'Windows NT 3.x',
'win,nt' => 'Windows NT',
'win,16' => 'Windows 3.x',
'win' => 'Windows',
'mac,68k' => 'MacOS 68k',
'mac,68000' => 'MacOS 68k',
'mac,os x' => 'Mac OS X',
'mac,ppc' => 'MacOS PPC',
'mac,powerpc' => 'MacOS PPC',
'macintosh' => 'MacOS',
'applesyndication' => 'Mac OS X', // Safari newsreader
'ubuntu' => 'Ubuntu Linux',
'debian' => 'Debian Linux',
'linux' => 'Linux',
'series80' => 'Series 80',
'amigaos' => 'AmigaOS',
'beos' => 'BeOS',
'os/2' => 'OS/2',
'webtv' => 'WebTV',
'sunos' => 'Sun/Solaris',
'irix' => 'Irix',
'hpux' => 'HP Unix',
'aix' => 'AIX',
'dec' => 'DEC-Alpha',
'alpha' => 'DEC-Alpha',
'osf1' => 'DEC-Alpha',
'ultrix' => 'DEC-Alpha',
'sco' => 'SCO',
'unix_sv' => 'SCO',
'vax' => 'VMS',
'openvms' => 'VMS',
'sinix' => 'Sinix',
'reliantunix' => 'Reliant/Unix',
'freebsd' => 'FreeBSD',
'openbsd' => 'OpenBSD',
'netbsd' => 'NetBSD',
'bsd' => 'BSD',
'unix_system_v' => 'UnixWare',
'ncr' => 'MPRAS',
'x11' => 'Unix'
);
}
} //class USER_AGENT_PARSE_TABLES

define ('User_agent_temporary_renderer', 1);
define ('User_agent_final_renderer', 2);
define ('User_agent_final_browser', 3);
define ('User_agent_final_browser_abort', 4);
define ('User_agent_final_browser_temporary_renderer', 5);

/***************************************/
class USER_AGENT_RENDERER_INFO {

var $id;
var $technology_name;
var $display_name;
var $precedence;

/***************************************/
function USER_AGENT_RENDERER_INFO ($id, $tech, $prec, $disp = '') {
$this->id = $id;
$this->technology_name = $tech;
if ($disp)
	$this->display_name = $disp;
else
	$this->display_name = $tech;
$this->precedence = $prec;
}

/***************************************/
function renderer_can_be_overridden () {
return ($this->precedence == User_agent_temporary_renderer) || ($this->precedence == User_agent_final_browser_temporary_renderer);
}

/***************************************/
function browser_can_be_overridden () {
return $this->precedence != User_agent_final_browser;
}

/***************************************/
function continue_processing_ids () {
return $this->precedence != User_agent_final_browser_abort;
}

/***************************************/
function is_mozilla_gecko ($ver) {
return ($this->id == Browser_netscape_4) && ($ver [0] > 4);
}
} //class USER_AGENT_RENDERER_INFO
?>